package com.ssdd.utilities;

import com.ssdd.chaskinetclient.Chat;
import com.ssdd.chaskinetclient.ChatRoom;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import javax.swing.JFrame;

/**
 *
 * @author jheorge
 */
//clase que permite al servidor tener varias conexiones ,entonces si alguien
//se conecta pueda serguir recibiendo mas conexiones
//creando un singleton para poder usuar los metodos de la clase en cualquier
//parte del programa sin instanciar el objeto cada ves
public class ConectionManager {

    private Map<String, JFrame> chatList;
    private Conection c;
    private String user;
    private String serverHost = "localhost";
    private int serverPort = 4444;

    public String getServerHost() {
	return serverHost;
    }

    public void setServerHost(String serverHost) {
	this.serverHost = serverHost;
    }

    public int getServerPort() {
	return serverPort;
    }

    public void setServerPort(int serverPort) {
	this.serverPort = serverPort;
    }

    public String getUser() {
	return user;
    }

    public void setUser(String user) {
	this.user = user;
    }

    private ConectionManager() {
    }
    private static ConectionManager singleton = null;

    private static void createInstance() {
	if (singleton == null) {
	    System.out.println("creando instancia...");
	    synchronized (ConectionManager.class) {
		if (singleton == null) {
		    singleton = new ConectionManager();
		}
	    }
	}
    }

    public static ConectionManager getInstance() {
	createInstance();
	return singleton;
    }

    public String userVerification(String user, String password) {
	String resp = null;
	try {
	    System.out.println("abriendo Socket .....");
	    Socket s = new Socket(serverHost, serverPort);
	    c = new Conection(s);
	    resp = c.sendLoginMessage(user, password);
	    if (resp != null && resp.length() > 0 && resp.equals("VALID")) {
		this.user = user;
	    } else {
		System.out.println("cerrando coneccion......");
		c.setItsAlive(false);
		s.close();
		s = null;
	    }
	} catch (IOException ex) {
	    ex.printStackTrace();
	}
	return resp;
    }

    public List<String> listAllUsersConnected() {
	return c.reciveAllUsersConnected(user);
    }

    public void registerANewFrame(String nameChatRoom, JFrame jFrame) {
	if (chatList == null) {
	    chatList = new HashMap<String, JFrame>();
	}
	chatList.put(nameChatRoom, jFrame);
    }

    public void updatePrincipalFrame(List<String> userList) {
	if (userList != null && !userList.isEmpty()) {
	    ((ChatRoom) chatList.get("PRINCIPAL")).reloadList(userList);
	}
    }

    public void updateChatFrame(String message, String messageOwner, String keyFrame) {
	String key = isKeyExist(keyFrame);
	if (key != null && key.length() > 0) {
	    ((Chat) chatList.get(key)).updateChatMessage(message);
	} else {
	    Chat chat = new Chat();
	    StringTokenizer token = new StringTokenizer(keyFrame, "#$#");
	    List<String> users = new ArrayList<String>();
	    //users.add(messageOwner);
	    while (token.hasMoreTokens()) {
		String recipient = token.nextToken();
		if (!this.user.equals(recipient)) {
		    users.add(recipient);
		}
	    }

	    if (token.countTokens() > 2) {
		chat.setTitle(ConectionManager.getInstance().getUser() + ", chat con varias usuarios ..");
	    } else {
		chat.setTitle(ConectionManager.getInstance().getUser() + ", chat con " + users);
	    }
	    chat.setUserListBasedTo(users);
	    chat.setMsgInChatMessage(message);
	    chat.show();
	    ConectionManager.getInstance().registerANewFrame(keyFrame, chat);
	}

    }

    public String isKeyExist(String key) {
	String keyResp = null;
	System.out.println("[isKeyExist] externalKey : " + key);
	StringTokenizer externalKeyToken = new StringTokenizer(key, "#$#");
	int externalKeyCount = externalKeyToken.countTokens();
	Iterator i = this.chatList.keySet().iterator();
	while (i.hasNext()) {
	    String internalKeyValue = (String) i.next();
	    System.out.println("[isKeyExist] internalKeyValue : " + internalKeyValue);
	    StringTokenizer internalKeyToken = new StringTokenizer(internalKeyValue, "#$#");
	    int count = 0;
	    if (internalKeyToken.countTokens() >= externalKeyCount) {
		while (internalKeyToken.hasMoreTokens()) {
		    String internalKeyValueTmp = internalKeyToken.nextToken();
		    System.out.println("iteracion internal :::::::::::::::::::::::::::");
		    externalKeyToken = new StringTokenizer(key, "#$#");
		    while (externalKeyToken.hasMoreTokens()) {
			System.out.println("iteracion external :::::::::::::::::::::::::::");
			String externalKeyValueTmp = externalKeyToken.nextToken();
			System.out.println("[isKeyExist] internalKeyValueTmp : " + internalKeyValueTmp);
			System.out.println("[isKeyExist] externalKeyValueTmp : " + externalKeyValueTmp);
			if (internalKeyValueTmp.equals(externalKeyValueTmp)) {
			    count++;
			    System.out.println("[isKeyExist] count : " + count);
			    break;
			}
		    }
		}
	    } else {
		count = 0;
	    }
	    if (count == externalKeyCount) {
		keyResp = internalKeyValue;
		break;
	    }
	    count = 0;
	}
	return keyResp;
    }

    public void sendMessage(String message, List<String> users) {
	if (message != null && message.length() > 0 && users != null && !users.isEmpty()) {
	    c.sendMessage(message, user, users);
	}
    }

    public void sendLogoutMessage() {
	c.sendLogoutMessage( user);
    }

    public void logoutOwner(){
	Iterator i = chatList.keySet().iterator();
	String key;
	while (i.hasNext()) {
	    key = (String) i.next();
	    if (!key.equals("PRINCIPAL")) {
		Chat chat = (Chat) chatList.get(key);
		chat.dispose();
	    }
	}
	((ChatRoom) chatList.get("PRINCIPAL")).dispose();
    }

    public void logout(String user) {
	System.out.println("entro a hacer logout de un usuario: " + user);
	// verificar si estoy con algun chat y si es asi  tengo que bloquear el boton enviar
	//y poner un mensaje der usuario fuera
	Iterator i = chatList.keySet().iterator();
	String key;
	while (i.hasNext()) {
	    key = (String) i.next();
	    if (!key.equals("PRINCIPAL")) {
		Chat chat = (Chat) chatList.get(key);
		chat.disableChat(user);
	    }
	}
	// quitar de la lista de usuarios
	((ChatRoom) chatList.get("PRINCIPAL")).reloadList(listAllUsersConnected());
    }
}
